/*
 * Login class for the login and registration window of the program
 * Author: Daniel Henderson
 * TCSS 360 Spring 2013 
 * University of Washington
 */

package View;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import Model.Controller;
import Model.Paper;
import Model.User;

/**
 * Constructor for the ProgramChair class, The program chair class is a JPanel
 * inside TabbedPane window of the application.
 * @author Daniel Henderson 
 */
public class ProgramChair extends JPanel {

	private static final long serialVersionUID = -7023182166181095835L;
	private Controller controller;
	private ScrollPane scroll;

	private JLabel reviewsDate;
	private JLabel recomendationsDate;
	private JLabel finalDecisionDate;
	private JLabel recommendations;
	private JLabel finalDecision;
	private Paper selectedPaper;
	private JComboBox userComboList;
	private Frame frame;

	// Label for JCombo Box
	private JLabel userLabel;

	//Labels inside the Asign SPC popup descriptionj
	private JLabel userFullnameDescr;
	private JLabel userLoginDescr;
	private JLabel userEmailDescr;

	//Labels inside the Asign SPC popup to hold information about the user selected
	private JLabel userFullname;
	private JLabel userLogin;
	private JLabel userEmail;

	//List for JCombo box to select User for SPC
	private List <String> UserUniqeLogin;
	private List <String> UserNames;
	private List <String> UserEmail;

	//Buttons for assigning SPC
	private JButton btnAssignSPCNOW;
	private JButton btnCancel;
	private JButton btnAssign;
	private JButton btnViewRationale;
	private JButton btnApproveReject;
	private JButton btnViewReviews;
	private JButton btnDownloadEmails;

	private User currentlySelectedUser;

	/**
	 * Constructor for the ProgramChair class, The program chair class is a JPanel
	 * inside TabbedPane window of the application.
	 * @author Daniel Henderson 
	 * @param control is the Controller from Model package.
	 */
	public ProgramChair(Controller control) {
		controller = control;
		scroll = new ScrollPane(controller, "pc");
		reviewsDate = new JLabel(" ");
		recomendationsDate = new JLabel(" ");
		finalDecisionDate = new JLabel(" ");
		recommendations = new JLabel(" ");
		finalDecision = new JLabel(" ");
		userFullname = new JLabel(" ");
		userLogin = new JLabel(" ");
		userEmail = new JLabel(" ");
		UserUniqeLogin = new ArrayList<String>();
		UserNames = new ArrayList<String>();
		UserEmail = new ArrayList<String>();
		userFullnameDescr = new JLabel("Full Name: ");
		userLoginDescr = new JLabel("Unique Login: ");
		userEmailDescr = new JLabel("Email Adress: ");
		userLabel = new JLabel("Users: ");
		btnAssignSPCNOW = new JButton("Assign SubProgram Chair");
		btnCancel = new JButton("Cancel"); 
		setup();
	}

	/**
	 * Sets up the basic look and catch selection change from JTable in JScrollPane
	 * by utilizing propertyChangeListener.
	 * @author Daniel Henderson
	 */
	private void setup() {
		final JLabel flag = new JLabel("pc");

		/*
		  Using property change listener to catch list selection changes in ScrollPane.
		  By passing in JLabel to ScrollPane, if setText is changed, JLabels on 
		  PC tab will change accordingly. If a paper is selected, the various
		  information for that paper will be displayed (deadlines, status, etc..)
		 */
		flag.addPropertyChangeListener(new PropertyChangeListener(){
			@Override
			public void propertyChange(PropertyChangeEvent e) {
				if (e.getSource() == flag && setSelectedPaper()) {
					for (Paper pcPapers : controller.getCurrentUser().getPCPapers()) {
						if ( selectedPaper.getUniqueCode() == pcPapers.getUniqueCode()) {//Paper match
							if(selectedPaper.getSPC() != null) {
								btnAssign.setEnabled(false);
							} else {
								btnAssign.setEnabled(true);
							}
							if(selectedPaper.getAcceptedStatus() != 0) {
								btnApproveReject.setEnabled(false);
							} else {
								btnApproveReject.setEnabled(true);
							}
							//Set Review Deadline
							int rev_day = pcPapers.getConference().getReviewsDeadline().getDateDay();
							int rev_month = pcPapers.getConference().getReviewsDeadline().getDateMonth();
							int rev_year = pcPapers.getConference().getReviewsDeadline().getDateYear();
							reviewsDate.setText(rev_month+ "/" + rev_day + "/" + rev_year);

							//set Recommendation Deadline
							int rec_day = pcPapers.getConference().getNotifyAuthorsDeadline().getDateDay();
							int rec_month = pcPapers.getConference().getNotifyAuthorsDeadline().getDateMonth();
							int rec_year = pcPapers.getConference().getNotifyAuthorsDeadline().getDateYear();
							recomendationsDate.setText(rec_month  + "/" +rec_day  + "/" + rec_year);

							//set Final Decision Deadline
							int finalDec_day = pcPapers.getConference().getPaperRevisionSubmissionDeadline().getDateDay();
							int finalDec_month = pcPapers.getConference().getPaperRevisionSubmissionDeadline().getDateMonth();
							int finalDec_year = pcPapers.getConference().getPaperRevisionSubmissionDeadline().getDateYear();
							finalDecisionDate.setText(finalDec_month + "/" + finalDec_day + "/" + finalDec_year);

							//check the recommendation status and print
							int recStatus = pcPapers.getRecommendation();
							if( recStatus == -1) {
								recommendations.setText("Not provided yet.");
							}
							else {
								recommendations.setText("" + recStatus);
							}

							//check Final Decision and display  (0=Undecided, 1=Acepted, 2=Rejected)
							String finalDecisionStatus = "Undecided.";
							int status = pcPapers.getAcceptedStatus();
							if( status == 1) {
								finalDecisionStatus = "Accepted.";
							}
							else if(status == 2) {
								finalDecisionStatus = "Rejected.";
							}
							finalDecision.setText(finalDecisionStatus);
						}
					}
				}
			}
		});

		scroll.setFlag(flag);
		JScrollPane pane = scroll.getScrollPane();
		pane.setWheelScrollingEnabled(true);

		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		add(pane);
		add(createContainer("Review Deadline : ", reviewsDate));
		add(createContainer("Recommendation Deadline : ", recomendationsDate));
		add(createContainer("Decision Deadline : ", finalDecisionDate));
		add(createContainer("Paper Recommendation : ", recommendations));
		add(createContainer("Final Decision : ", finalDecision));
		add(btns());
	} //setup

	/**
	 * Formatting the buttons and labels to a certain look using FlowLayout.
	 * @author Ching-Ting Huang
	 * @author Daniel Henderson (edited for the look to stay consistent)
	 * @return the Container containing both label and button.
	 */
	private Container createContainer(String labelname, Container theContainer) {
		Container flow = new JPanel(new FlowLayout(FlowLayout.CENTER));
		JLabel lbl = new JLabel(labelname);
		flow.add(lbl);
		flow.add(theContainer);
		return flow;
	}

	/**
	 * Formatting the buttons to a certain look using FlowLayout as well as setting
	 * up their actionListener functionality when the buttons are clicked.
	 * @author Daniel Henderson
	 * @return the Container containing the buttons.
	 */
	private Container btns() {
		Container contain = new JPanel(new FlowLayout(FlowLayout.CENTER));
		btnAssign = new JButton("Assign Subprogram Chair");
		btnViewRationale = new JButton("View Rec. Rationale");
		btnApproveReject = new JButton("Approve/Reject Paper");
		btnViewReviews = new JButton("View Reviews");
		btnDownloadEmails = new JButton("Download SPC Emails");

		//Assign SPC setup Listener for the Add SPC window
		btnAssignSPCNOW.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnAssignSPCNOW) {
					if(userComboList.getSelectedIndex() != -1) {
						controller.assignSPC(selectedPaper, currentlySelectedUser);
						JOptionPane.showMessageDialog(null, "The User " +currentlySelectedUser.getfullname() + " has been set as the SubProgram Chair for this paper."); 
						frame.dispose();
						clearUserNameLists();
					}
					else {
						JOptionPane.showMessageDialog(null, "Please select a user from the pull down menu to assign them as program chair for this manuscript."); 
					}
				}
			}
		});

		btnCancel.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnCancel) {
					frame.dispose();
					clearUserNameLists();
				}
			}
		});
		
		//Setup listener to open the assign SPC window
		btnAssign.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnAssign && setSelectedPaper()) {
					final List<User> theUsers = controller.getUserList();
					//Populate the User String list for the Conference JComboBox
					clearUserNameLists();
					for(int i = 0; i < theUsers.size(); i++) {	
						if (!theUsers.get(i).getLogin().equals(controller.getCurrentUser().getLogin())) { //DO NOT INCLUDE THE PCchair in the list
							if(!theUsers.get(i).getLogin().equals(selectedPaper.getAuthor().getLogin())) {//Do not include the author
								
								UserUniqeLogin.add(theUsers.get(i).getLogin());
								UserNames.add(theUsers.get(i).getfullname());
								UserEmail.add(theUsers.get(i).getEmail());
							}
						}
					}
					final String[] users = Arrays.copyOf(UserNames.toArray(), UserNames.size(), String[].class);

					userComboList = new JComboBox(users);
					userComboList.setSelectedItem(null);
					userComboList.addActionListener(new ActionListener(){

						@Override
						public void actionPerformed(ActionEvent e) {
							JComboBox cb = (JComboBox) e.getSource();
							if (cb == userComboList) {
								int userIndex = cb.getSelectedIndex();
								userFullname.setText(UserNames.get(userIndex));
								userLogin.setText(UserUniqeLogin.get(userIndex));
								userEmail.setText(UserEmail.get(userIndex));
								for(int i = 0; i < theUsers.size(); i++) {
									User tempUser = theUsers.get(i);
									if(tempUser.getfullname() == UserNames.get(userIndex) &&
											tempUser.getEmail() == UserEmail.get(userIndex) &&
											tempUser.getLogin() == UserUniqeLogin.get(userIndex))
										currentlySelectedUser = tempUser;

								}
							}
						}});
					JPanel panel = new JPanel();
					GridBagLayout gridbag = new GridBagLayout();
					GridBagConstraints c = new GridBagConstraints();
					panel.setLayout(gridbag);

					//Set GridBag constraints
					c.gridwidth = GridBagConstraints.REMAINDER; //last
					c.anchor = GridBagConstraints.WEST;
					c.weightx = 1.0;
					panel.setBorder(
							BorderFactory.createCompoundBorder(
									BorderFactory.createTitledBorder("Assign SubProgram Chair to Manuscript"),
									BorderFactory.createEmptyBorder(5,5,5,5)));
					frame = new JFrame();
					//frame.setPreferredSize(preferredSize)
					JDialog dialog = new JDialog(frame, 
							"Submit A Paper",
							true);
					dialog.setContentPane(panel);
					Dimension windowSize = new Dimension(425, 300);
					frame.setPreferredSize(windowSize);
					dialog.setPreferredSize(windowSize);
					dialog.setDefaultCloseOperation(
							JDialog.DO_NOTHING_ON_CLOSE);

					GridBagConstraints labelConstraints = new GridBagConstraints();
					labelConstraints.insets = new Insets(10,0,0,0);
					labelConstraints.anchor = GridBagConstraints.EAST;
					labelConstraints.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
					labelConstraints.fill = GridBagConstraints.NONE;      //reset to default
					labelConstraints.weightx = 0.0;                       //reset to default

					GridBagConstraints textConstraints = new GridBagConstraints();
					textConstraints.insets = new Insets(10,0,0,0);
					textConstraints.anchor = GridBagConstraints.EAST;
					textConstraints.gridwidth = GridBagConstraints.REMAINDER;     //end row
					textConstraints.fill = GridBagConstraints.HORIZONTAL;
					textConstraints.weightx = 1.0;


					//Add Conference Selection
					panel.add(userLabel, labelConstraints);
					panel.add(userComboList, textConstraints);

					//Add Deadline Display
					panel.add(userFullnameDescr, labelConstraints);
					panel.add(userFullname, textConstraints);

					panel.add(userLoginDescr, labelConstraints);
					panel.add(userLogin, textConstraints);

					panel.add(userEmailDescr, labelConstraints);
					panel.add(userEmail, textConstraints);

					btnAssignSPCNOW.setPreferredSize(new Dimension(200, 25));
					btnCancel.setPreferredSize(new Dimension(200, 25));
					textConstraints.fill = GridBagConstraints.VERTICAL;

					panel.add(btnAssignSPCNOW, textConstraints);
					panel.add(btnCancel, textConstraints);

					frame.add(panel);
					frame.setVisible(true);
					frame.setResizable(true);
					frame.pack();
					frame.setLocationRelativeTo(null);
				}
			}
		});

		//setup ApproveReject Button for main PC panel
		btnApproveReject.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnApproveReject && setSelectedPaper()) {
					if(selectedPaper.getRationale() != null) {//not null
						if(!selectedPaper.getRationale().isEmpty()) {//not empty
							Object[] options = { "Accept", "Reject", "Cancel" };
							int selectedValue = JOptionPane.showOptionDialog(null, "Please choose whether to accept or reject the manuscript.",
									null, JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
									null, options, options[0]);
							if(selectedValue == 0) {
								JOptionPane.showMessageDialog(null, "The paper has been accepted!"); 
								controller.approveRejectPaper(1, selectedPaper);
								finalDecision.setText("Accepted.");
							}
							else if(selectedValue == 1) {
								controller.approveRejectPaper(2, selectedPaper);
								JOptionPane.showMessageDialog(null, "The paper has been rejected!"); 
								finalDecision.setText("Rejected.");
							}
							else if(selectedValue == 2) {
								//do nothing, just close dialog automatically
							}
						}
						else {
							JOptionPane.showMessageDialog(null, "No Recommendation has been given from the SubProgram Chair. You cannot reject or accept a paper before this recommendation is given."); 
						}

					} else {
						JOptionPane.showMessageDialog(null, "No Recommendation has been given from the SubProgram Chair. You cannot reject or accept a paper before this recommendation is given."); 
					}

				}
			}
		});

		/*setup View Reviews Button for main PC panel
		 * This functionality will not be implemented in 
		 * the first iteration. This is not one for the
		 * required User Stories
		 */
		btnViewReviews.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnViewReviews) {
					if (scroll.getSelectedRowNum() != -1) {
						Object[] selected = scroll.getRow(scroll.getSelectedRowNum());
						Paper chosen = (Paper)selected[4];
						Paper paper = null;
						for (int i = 0; i < controller.getCurrentUser().getPCPapers().size(); i++) {
							if (chosen.getUniqueCode() == controller.getCurrentUser().getPCPapers().get(i).getUniqueCode()) {
								paper = controller.getCurrentUser().getPCPapers().get(i);
							}
						}
						
						new ViewReview(paper);

					} else {
						JOptionPane.showMessageDialog(null, "Please select a manuscript to view reviews.",
								"Select Manuscript", JOptionPane.WARNING_MESSAGE);
					}
				}
			}
		});

		//setup Download Emails Button for main PC panel
		btnDownloadEmails.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnDownloadEmails) {
					File file;
					file = controller.getSubProgramChairEmailAddresses();
					JOptionPane.showMessageDialog(null, "Saved " + file.getName()+ " - Email list saved to file."); 
				}
			}
		});
		
		//setup View Rationale Button for main PC panel
		btnViewRationale.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JTextArea textarea = new JTextArea();;
				if (e.getSource() == btnViewRationale && setSelectedPaper()) {
					if(selectedPaper.getRationale() == null) {
						System.out.println("RATIONALE NULL");
						textarea.setText("The rationale for this paper has not yet been set.");
					}
					else if(selectedPaper.getRationale().length() < 1) { //no rationale set yet
						textarea.setText("The rationale for this paper has not yet been set.");
					}
					else {
						textarea.setText("Recommendation: [" + selectedPaper.getRecommendation() + "]" + 
										"    Rationale: " + selectedPaper.getRationale());
					}
					textarea.setEditable(false);
					JPanel panel = new JPanel();
					GridBagLayout gridbag = new GridBagLayout();
					GridBagConstraints c = new GridBagConstraints();
					panel.setLayout(gridbag);

					//Set GridBag constraints
					c.gridwidth = GridBagConstraints.REMAINDER; //last
					c.anchor = GridBagConstraints.WEST;
					c.weightx = 1.0;
					panel.setBorder(
							BorderFactory.createCompoundBorder(
									BorderFactory.createTitledBorder("View Recommendation Rationale"),
									BorderFactory.createEmptyBorder(5,5,5,5)));
					frame = new JFrame();
					JDialog dialog = new JDialog(frame, 
							"Submit A Paper",
							true);
					dialog.setContentPane(panel);
					Dimension windowSize = new Dimension(425, 300);
					frame.setPreferredSize(windowSize);
					dialog.setPreferredSize(windowSize);
					dialog.setDefaultCloseOperation(
							JDialog.DO_NOTHING_ON_CLOSE);

					GridBagConstraints labelConstraints = new GridBagConstraints();
					labelConstraints.insets = new Insets(10,0,0,0);
					labelConstraints.anchor = GridBagConstraints.EAST;
					labelConstraints.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
					labelConstraints.fill = GridBagConstraints.NONE;      //reset to default
					labelConstraints.weightx = 0.0;                       //reset to default

					GridBagConstraints textConstraints = new GridBagConstraints();
					textConstraints.insets = new Insets(10,0,0,0);
					textConstraints.anchor = GridBagConstraints.EAST;
					textConstraints.gridwidth = GridBagConstraints.REMAINDER;     //end row
					textConstraints.fill = GridBagConstraints.HORIZONTAL;
					textConstraints.weightx = 1.0;

					panel.add(textarea, textConstraints);
					btnCancel.setPreferredSize(new Dimension(200, 25));
					textConstraints.fill = GridBagConstraints.VERTICAL;
					panel.add(btnCancel, textConstraints);

					frame.add(panel);
					frame.setVisible(true);
					frame.setResizable(true);
					frame.pack();
					frame.setLocationRelativeTo(null);
				}

			}
		});

		contain.add(btnAssign);
		contain.add(btnViewRationale);
		contain.add(btnApproveReject);
		contain.add(btnViewReviews);
		contain.add(btnDownloadEmails);
		return contain;
	}
	
	/**
	 * Used to print out title for tabbed panes.
	 */
	public String getName() {
		return "Program Chair";
	}

	/**
	 * Helper method used to set the selected paper when the
	 * user selectes a manuscript inside the scrollpane window.
	 * @author Daniel Henderson
	 */
	private boolean setSelectedPaper() {
		boolean isPaperSet;
		if (scroll.getSelectedRowNum() != -1) {
			isPaperSet = true;
			Object[] selected = scroll.getRow(scroll.getSelectedRowNum());
			Paper currentPaper = (Paper) selected[4];
			List<Paper> pcPapers = controller.getCurrentUser().getPCPapers();
			for (int i = 0; i < pcPapers.size(); i++) {
				if (currentPaper.getUniqueCode() == pcPapers.get(i).getUniqueCode()) {
					selectedPaper = currentPaper;
				}
			}
		} else {
			isPaperSet = false;
			JOptionPane.showMessageDialog(null, "Please select a manuscript...",
					"Select Manuscript", JOptionPane.WARNING_MESSAGE);
		}
		return isPaperSet;

	}
	
	/**
	 * Helper method used to clear the lists of User information
	 * that populates a JComboBox. Once the user is selected,
	 * the previous data needs to be removed.
	 * @author Daniel Henderson
	 */
	private void clearUserNameLists() {
		UserUniqeLogin.clear();
		UserNames.clear();
		UserEmail.clear();
	}
}
